home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / libkb100.zip / LIBKB-1.00 / SRC / MKTABLES.C < prev   
C/C++ Source or Header  |  1996-07-23  |  16KB  |  619 lines

  1. /* mktables.c -- make keyboard tables _kbtable.hh
  2.  * Copyright (C) 1995, 1996 Markus F.X.J. Oberhumer
  3.  * For conditions of distribution and use, see copyright notice in kb.h 
  4.  */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <assert.h>
  11.  
  12. #include <kb.h>
  13. #include "_kb.h"
  14.  
  15. #if defined(__KB_MSDOS)
  16. #  include <io.h>
  17. #  include <fcntl.h>
  18. #endif
  19.  
  20.  
  21.  
  22. /***********************************************************************
  23. //
  24. ************************************************************************/
  25.  
  26. static unsigned char prefix_scancode[128];
  27. static unsigned char inverse_prefix_scancode[128];
  28.  
  29. static unsigned short shift_state_table[128];
  30. static unsigned short unshift_state_table[128];
  31.  
  32.  
  33. typedef unsigned short table_t;
  34.  
  35. static table_t alt_table[128];
  36. static table_t control_table[128];
  37.  
  38.  
  39. /***********************************************************************
  40. // prefix tables 
  41. ************************************************************************/
  42.  
  43. static void init_prefix_tables(void)
  44. {
  45.     int i;
  46.     unsigned char *t;
  47.  
  48.     t = prefix_scancode;    /* E0 table */
  49.  
  50.     /* unknown prefix codes map to scancode 0 */
  51.     for (i = 0; i < 128; i++)
  52.         t[i] = KB_SCAN_UNKNOWN;
  53.  
  54.     /* prefixed keys which map to keypad */
  55.     t[KB_SCAN_SLASH]     = KB_SCAN_DIVIDE_PAD;
  56.     t[KB_SCAN_ENTER]     = KB_SCAN_ENTER_PAD;
  57.  
  58.     /* prefixed keys on keypad which map to other keys */
  59.     t[KB_SCAN_MULTIPLY_PAD] = KB_SCAN_PRINT;
  60.     t[KB_SCAN_7_PAD]     = KB_SCAN_HOME;
  61.     t[KB_SCAN_8_PAD]     = KB_SCAN_UP;
  62.     t[KB_SCAN_9_PAD]     = KB_SCAN_PGUP;
  63.     t[KB_SCAN_4_PAD]     = KB_SCAN_LEFT;
  64.     t[KB_SCAN_6_PAD]     = KB_SCAN_RIGHT;
  65.     t[KB_SCAN_1_PAD]     = KB_SCAN_END;
  66.     t[KB_SCAN_2_PAD]     = KB_SCAN_DOWN;
  67.     t[KB_SCAN_3_PAD]     = KB_SCAN_PGDN;
  68.     t[KB_SCAN_0_PAD]     = KB_SCAN_INSERT;
  69.     t[KB_SCAN_PERIOD_PAD] = KB_SCAN_DELETE;
  70.  
  71.     /* prefixed shift keys */
  72.     t[KB_SCAN_LCONTROL]  = KB_SCAN_RCONTROL;
  73.     t[KB_SCAN_ALT]       = KB_SCAN_ALTGR;
  74.     t[KB_SCAN_LSHIFT]    = KB_SCAN_UNUSED_VIRTUAL;
  75.     t[KB_SCAN_RSHIFT]    = KB_SCAN_UNUSED_VIRTUAL;
  76.  
  77.     /* prefixed special keys */
  78.     t[KB_SCAN_NUMLOCK]   = KB_SCAN_PAUSE_VIRTUAL;
  79.     t[KB_SCAN_SCRLOCK]   = KB_SCAN_CONTROL_BREAK_VIRTUAL;
  80.  
  81.     for (i = KB_SCAN_F12 + 1; i < 128; i++)
  82.         assert(prefix_scancode[i] == KB_SCAN_UNKNOWN);
  83.  
  84.     /* New Microsoft keyboard is rumoured to have
  85.      * e0 5b (left window button), e0 5c (right window button),
  86.      * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
  87.      * [or: Windows_L, Windows_R, TaskMan]
  88.      */
  89.     t[0x5b] = KB_SCAN_LBANNER;
  90.     t[0x5c] = KB_SCAN_RBANNER;
  91.     t[0x5d] = KB_SCAN_RMENU;
  92.  
  93.     for (i = KB_SCAN_MAX_RAW + 1; i < 128; i++)
  94.         assert(prefix_scancode[i] == KB_SCAN_UNKNOWN);
  95.  
  96.     t = inverse_prefix_scancode;
  97.     for (i = 0; i < 128; i++)
  98.         t[i] = i;
  99.     for (i = 0; i < 128; i++)
  100.         if (prefix_scancode[i] != KB_SCAN_UNKNOWN)
  101.             t[prefix_scancode[i]] = i;
  102. }
  103.  
  104.  
  105. /***********************************************************************
  106. // shift-state tables 
  107. ************************************************************************/
  108.  
  109. static void init_shift_state_tables(void)
  110. {
  111.     int i;
  112.     unsigned short *t;
  113.     const unsigned short virt = KB_SHIFT_VIRTUAL | KB_SHIFT_NO_PRESS;
  114.     const unsigned short unkn = KB_SHIFT_UNKNOWN | KB_SHIFT_NO_PRESS;
  115.  
  116.     t = shift_state_table;
  117.     for (i = 0; i < 128; i++)
  118.         t[i] = 0;
  119.  
  120. /* shift keys */
  121.     t[KB_SCAN_LSHIFT]           |= KB_SHIFT_LSHIFT | KB_SHIFT_NO_PRESS;
  122.     t[KB_SCAN_RSHIFT]           |= KB_SHIFT_RSHIFT | KB_SHIFT_NO_PRESS;
  123.     t[KB_SCAN_LCONTROL]         |= KB_SHIFT_LCONTROL | KB_SHIFT_NO_PRESS;
  124.     t[KB_SCAN_RCONTROL]         |= KB_SHIFT_RCONTROL | KB_SHIFT_NO_PRESS;
  125.     t[KB_SCAN_ALT]              |= KB_SHIFT_ALT | KB_SHIFT_NO_PRESS;
  126.     t[KB_SCAN_ALTGR]            |= KB_SHIFT_ALTGR | KB_SHIFT_NO_PRESS;
  127.  
  128. /* these are toggles and therefore not in the unshift state table */
  129.     t[KB_SCAN_CAPSLOCK]         |= KB_SHIFT_CAPSLOCK | KB_SHIFT_NO_PRESS;
  130.     t[KB_SCAN_NUMLOCK]          |= KB_SHIFT_NUMLOCK | KB_SHIFT_NO_PRESS;
  131.     t[KB_SCAN_SCRLOCK]          |= KB_SHIFT_SCRLOCK | KB_SHIFT_NO_PRESS;
  132.  
  133. /* these are toggles that DO produce a keypress */
  134.     t[KB_SCAN_INSERT]           |= KB_SHIFT_INSERT;
  135.  
  136. /* these are toggles for virtual keys */
  137.     t[KB_SCAN_CONTROL_BREAK_VIRTUAL] |= KB_SHIFT_CONTROL_BREAK | virt;
  138.     t[KB_SCAN_PAUSE_VIRTUAL]    |= KB_SHIFT_PAUSE | virt;
  139.  
  140. /* other virtual keys */
  141.     t[KB_SCAN_UNUSED_VIRTUAL]   |= virt;
  142.  
  143. /* other keys */
  144.     t[KB_SCAN_LAST_CONSOLE]     |= KB_SHIFT_NO_PRESS;
  145.     t[KB_SCAN_LBANNER]          |= KB_SHIFT_NO_PRESS;
  146.     t[KB_SCAN_RBANNER]          |= KB_SHIFT_NO_PRESS;
  147.     t[KB_SCAN_RMENU]            |= KB_SHIFT_NO_PRESS;
  148.     /* t[KB_SCAN_PRINT] |= KB_SHIFT_NO_PRESS; Ctrl+Print DOES generate a code */
  149.  
  150. /* unknown keys */
  151.     i = KB_SCAN_UNKNOWN;
  152.     if (t[i] == 0)
  153.         t[i] |= unkn;
  154.     i = 85;
  155.     if (t[i] == 0)
  156.         t[i] |= unkn;
  157.     for (i = 89; i < 96; i++)
  158.         if (t[i] == 0)
  159.             t[i] |= unkn;
  160.     for (i = 112; i < 128; i++)
  161.         if (t[i] == 0)
  162.             t[i] |= unkn;
  163.  
  164. /* NOT USED */
  165. #if defined(KB_SHIFT_NO_NAME)
  166.     for (i = 0; i < 128; i++)
  167.     {
  168.         const char *p = kb_keyname(i);
  169.         if (p == NULL || *p == 0)
  170.             t[i] |= KB_SHIFT_NO_NAME;
  171.     }
  172. #endif
  173.  
  174.  
  175.     t = unshift_state_table;
  176.     for (i = 0; i < 128; i++)
  177.         t[i] = 0;
  178.     t[KB_SCAN_LSHIFT]   = KB_SHIFT_LSHIFT;
  179.     t[KB_SCAN_RSHIFT]   = KB_SHIFT_RSHIFT;
  180.     t[KB_SCAN_LCONTROL] = KB_SHIFT_LCONTROL;
  181.     t[KB_SCAN_RCONTROL] = KB_SHIFT_RCONTROL;
  182.     t[KB_SCAN_ALT]      = KB_SHIFT_ALT;
  183.     t[KB_SCAN_ALTGR]    = KB_SHIFT_ALTGR;
  184.  
  185. /* negate for use with & (and) */
  186.     for (i = 0; i < 128; i++)
  187.         t[i] = ~t[i];
  188. }
  189.  
  190.  
  191.  
  192. /***********************************************************************
  193. // utility stuff
  194. ************************************************************************/
  195.  
  196. static int no_code(int i)
  197. {
  198.     assert(i >= 0 && i < 128);
  199.  
  200.     return KB_ANY_MASK(shift_state_table[i],
  201.         (KB_SHIFT_NO_PRESS | KB_SHIFT_UNKNOWN | KB_SHIFT_VIRTUAL));
  202. }
  203.  
  204.  
  205. static int default_code(int i)
  206. {
  207.     assert(i >= 0 && i < 128);
  208.  
  209.     if (no_code(i))
  210.         return 0;
  211.  
  212.     if (i >= KB_SCAN_F1 && i <= KB_SCAN_F10)
  213.         return 0;
  214.     if (i >= KB_SCAN_F11 && i <= KB_SCAN_F12)
  215.         return 0;
  216.     if (i == KB_SCAN_PRINT)
  217.         return 0;
  218.     
  219.     return inverse_prefix_scancode[i];
  220. }
  221.  
  222.  
  223. static void cleanup_table(table_t *t)
  224. {
  225.     int i;
  226.  
  227.     for (i = 0; i < 128; i++)
  228.         if (no_code(i))
  229.             t[i] = 0;
  230. }
  231.  
  232.  
  233. /***********************************************************************
  234. // These tables are hardcoded for American keyboards.
  235. ************************************************************************/
  236.  
  237. /* unshifted ASCII for scan codes */
  238. static table_t plain_table[128] =
  239. {
  240. /*    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F           */
  241.     0  ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8  ,9  ,   /* 0 */
  242.     'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0  ,'a','s',   /* 1 */
  243.     'd','f','g','h','j','k','l',';',39 ,'`',0  ,92 ,'z','x','c','v',   /* 2 */
  244.     'b','n','m',',','.','/',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,   /* 3 */
  245.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',   /* 4 */
  246.     '2','3','0','.',0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,   /* 5 */
  247.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,   /* 6 */
  248.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0      /* 7 */
  249. };
  250.  
  251. /* shifted ASCII for scan codes */
  252. static table_t shift_table[128] =
  253. {
  254. /*    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F           */
  255.     0  ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8  ,9  ,   /* 0 */
  256.     'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0  ,'A','S',   /* 1 */
  257.     'D','F','G','H','J','K','L',':',34 ,'~',0  ,'|','Z','X','C','V',   /* 2 */
  258.     'B','N','M','<','>','?',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,   /* 3 */
  259.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',   /* 4 */
  260.     '2','3','0','.',0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,   /* 5 */
  261.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,   /* 6 */
  262.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0      /* 7 */
  263. };
  264.  
  265.  
  266. static void prepare_table(table_t *t)
  267. {
  268.     int i;
  269.  
  270.     t[KB_SCAN_ENTER_PAD] = 13;
  271.     t[KB_SCAN_DIVIDE_PAD] = '/';
  272.     if (t[KB_SCAN_LESS] == 0)
  273.         t[KB_SCAN_LESS] = t[KB_SCAN_BACKSLASH];
  274.  
  275.     for (i = 0; i < 128; i++)
  276.         if (t[i] == 0)
  277.             t[i] = default_code(i);
  278. }
  279.  
  280.  
  281. static void init_plain_table(void)
  282. {
  283.     table_t *t = plain_table;
  284.     int i, j;
  285.  
  286.     prepare_table(t);
  287.     for (i = j = KB_SCAN_F1; i